package com.coocaa.typhoon.api.v1.userfile.provider;


import com.coocaa.typhoon.api.third.volcengine.model.video.VideoInfo;
import com.coocaa.typhoon.api.third.volcengine.service.TOSService;
import com.coocaa.typhoon.api.v1.userfile.cache.TaskProgressCache;
import com.coocaa.typhoon.api.v1.userfile.constant.UploadTypeConstant;
import com.coocaa.typhoon.api.v1.userfile.model.ExtraSaveDTO;
import com.coocaa.typhoon.api.v1.userfile.model.UploadTmpResult;
import com.coocaa.typhoon.api.v1.userfile.model.input.UploadDataModel;
import com.coocaa.typhoon.api.v1.userfile.model.output.TaskProgressResultModel;
import com.coocaa.typhoon.api.v1.userfile.util.FileTypeCheckUtil;
import com.coocaa.typhoon.api.v1.userfile.util.TosFinalUrlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;

/**
 * @author bijiahao
 * @date : 2025/9/20 23:01
 * @description
 */
@Slf4j
@Service
public class UserFileAsyncProvider {
    @Autowired
    private TaskProgressCache taskProgressCache;
    @Autowired
    private TOSService tosService;
    @Autowired
    private PdfFileUploadProvider pdfFIleUploadProvider;
    @Autowired
    private UserFileAfterUploadProvider userFileAfterUploadProvider;
    @Autowired
    private PptFileUploadProvider pptFileUploadProvider;
    @Autowired
    private VideoFileUploadProvider videoFileUploadProvider;

    public UploadTmpResult upload(String taskId, File localSaveFile, String fileLocalPath, String userId, UploadDataModel dataModel) {
        try {
            UploadTmpResult uploadTmpResult = tosService.uploadFile(localSaveFile, fileLocalPath, (TaskProgressResultModel progress) -> {
                taskProgressCache.setTaskProgressCache(taskId, progress);
            });
            //设置时长
            setDuration(uploadTmpResult);
            //上传后处理
            doAfterUpload(fileLocalPath, uploadTmpResult, userId, dataModel);
            return uploadTmpResult;
        } catch (Exception e) {
            log.error("upload", e);
            return null;
        } finally {
            FileUtils.deleteQuietly(new File(fileLocalPath));
        }
    }

    private void setDuration(UploadTmpResult uploadTmpResult) {
        if (!FileTypeCheckUtil.isAudioVideo(uploadTmpResult.getFileExtName())) {
            return;
        }
        try {
            String videoFilePath = TosFinalUrlUtil.getFilePath(uploadTmpResult.getTosLink());
            VideoInfo videoInfo = tosService.getVideoInfo(videoFilePath);
            if (null == videoInfo) {
                return;
            }
            VideoInfo.Format format = videoInfo.getFormat();
            if (null == format) {
                return;
            }
            Double duration = Double.valueOf(format.getDuration());
            if (null == duration) {
                return;
            }
            int millis = (int) Math.floor(duration * 1000);
            uploadTmpResult.setDuration(millis);
        } catch (Exception e) {
            log.error("setDuration", e);
        }
    }

    /**
     * 上传后处理
     *
     * @param fileLocalPath
     * @param uploadTmpResult
     * @param userId
     * @param dataModel
     * @throws Exception
     */
    private void doAfterUpload(String fileLocalPath, UploadTmpResult uploadTmpResult, String userId, UploadDataModel dataModel) throws Exception {
        if (FileTypeCheckUtil.isCanSplitImage(uploadTmpResult.getFileExtName())) {
            handleSplitImage(fileLocalPath, uploadTmpResult, userId, dataModel);
        } else {
            if (!UploadTypeConstant.isSearchFile(dataModel.getUploadType())) {
                //向量化存储处理
                userFileAfterUploadProvider.handleAfterUpload(uploadTmpResult, userId);
            }
        }
    }

    private void handleSplitImage(String fileLocalPath, UploadTmpResult uploadTmpResult, String userId, UploadDataModel dataModel) throws Exception {
        if (FileTypeCheckUtil.isVideoExtension(uploadTmpResult.getFileExtName())) {
            videoFileUploadProvider.splitUploadImage(uploadTmpResult);
            return;
        }
        List<UploadTmpResult> uploadTmpResultList = null;
        try (InputStream cachedStream = Files.newInputStream(new File(fileLocalPath).toPath())) {
            if (FileTypeCheckUtil.isPDF(uploadTmpResult.getFileExtName())) {
                //pdf
                uploadTmpResultList = pdfFIleUploadProvider.splitUploadImage(cachedStream, uploadTmpResult);
            } else if (FileTypeCheckUtil.isPPTExtension(uploadTmpResult.getFileExtName())) {
                //PPT
                uploadTmpResultList = pptFileUploadProvider.splitUploadImage(cachedStream, uploadTmpResult);
            }
        }
        if (!FileTypeCheckUtil.isVideoExtension(uploadTmpResult.getFileExtName())) {
            ExtraSaveDTO extraSaveDTO = ExtraSaveDTO.builder()
                    .parentFileType(uploadTmpResult.getFileExtName())
                    .duration(uploadTmpResult.getDuration())
                    .build();
            userFileAfterUploadProvider.handleAfterUpload(uploadTmpResultList, userId, dataModel, extraSaveDTO);
        }
    }

    @Async("uploadThreadPoolExecutor")
    public void uploadAsync(String taskId, File localSaveFile, String fileLocalPath, String userId, UploadDataModel dataModel) {
        try {
            UploadTmpResult uploadTmpResult = tosService.uploadFile(localSaveFile, fileLocalPath, (TaskProgressResultModel progress) -> {
                taskProgressCache.setTaskProgressCache(taskId, progress);
            });
            //上传后处理
            doAfterUpload(fileLocalPath, uploadTmpResult, userId, dataModel);
        } catch (Exception e) {
            log.error("upload", e);
        } finally {
            FileUtils.deleteQuietly(new File(fileLocalPath));
        }
    }
}
